package com.societyGames.dotsExercises
{
import com.societyGames.dotsExercises.*;
	import com.societyGames.action.ActionQueue;
	import com.societyGames.action.CallbackAction;
	import com.societyGames.action.DelayAction;
	import com.societyGames.action.FunctionAction;
	import com.societyGames.system.EventObject;
	
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	import flash.text.TextLineMetrics;

	public class DotsRender extends Sprite
	{
		private static const DISPLAY_WIDTH:int = 250; //TODO: Move this to shared location.
		private static const DISPLAY_HEIGHT:int = 250;
		
		private var _dotsSimulation:DotsSimulation;
		private var _actionQueue:ActionQueue;
		private var _strokeSprite:Sprite = new Sprite();
		private var _spaceWidth:int;
		private var _spaceHeight:int;
		private var _strokeCount:TextField = new TextField();
		private var _actualStrokeCount:int;
		private var _desiredStrokeCount:int;
		
		public function DotsRender(dotsSimulation:DotsSimulation, actionQueue:ActionQueue, spaceWidth:int, spaceHeight:int)
		{
			this._dotsSimulation = dotsSimulation;
			this._actionQueue = actionQueue;
			this._spaceWidth = spaceWidth;
			this._spaceHeight = spaceHeight;

			//Setup the stroke count display
			this._strokeCount = new TextField();
			this._strokeCount.textColor = 0x888888;
			this._strokeCount.alpha = 0.3;
			this._strokeCount.width = DISPLAY_WIDTH;
			
			var textFormat:TextFormat = this._strokeCount.defaultTextFormat;
			textFormat.align = TextFormatAlign.CENTER;
			textFormat.size = 64;
			this._strokeCount.defaultTextFormat = textFormat;			
			
			this._strokeCount.text = "0/0";

			var metrics:TextLineMetrics = this._strokeCount.getLineMetrics(0);
			this._strokeCount.height = metrics.height + 4;
			
			this._strokeCount.y =(DISPLAY_HEIGHT / 2) - (this._strokeCount.textHeight / 2);			
			this.addChild(this._strokeCount);
			//Dots
			drawDots();
			//Stroke Sprite.
			this.addChild(this._strokeSprite);
		}

		private function drawDots():void
		{
			for (var gridX:int = 0; gridX < this._dotsSimulation.gridWidth; gridX++)
			{
				for (var gridY:int = 0; gridY < this._dotsSimulation.gridHeight; gridY++)
				{
					var dotSpaceRender:DotSpaceRender = new DotSpaceRender(gridY * this._dotsSimulation.gridWidth + gridX, this._spaceWidth, this._spaceHeight);
					dotSpaceRender.x = gridX * this._spaceWidth;
					dotSpaceRender.y = gridY * this._spaceHeight; 
					this.addChild(dotSpaceRender);
				}	
			}
		}
		
		public function setDesiredStrokeCount(value:int):void
		{
			this._desiredStrokeCount = value;
			synchronizeStrokeCount();
		}
		
		public function setActualStrokeCount(value:int):void
		{
			this._actualStrokeCount = value;
			synchronizeStrokeCount();			
		}
		
		private function synchronizeStrokeCount():void
		{
			this._actionQueue.add(new FunctionAction(setStrokeCountDisplay, this._actualStrokeCount, this._desiredStrokeCount));	
		}
		
		private function setStrokeCountDisplay(actualStrokeCount:int, desiredStrokeCount:int):void
		{
			this._strokeCount.text = actualStrokeCount + "/" + desiredStrokeCount;
		}
		
		public function drawConnection(start:int, end:int):void
		{
			this._actionQueue.add(new FunctionAction(connect, start, end, 0x000000));
			this._actionQueue.add(new DelayAction(250));
		}
		
		public function drawInvalidConnection(start:int, end:int):void
		{
			this._actionQueue.add(new FunctionAction(connect, start, end, 0xFF0000));
			this._actionQueue.add(new DelayAction(250));
		}
		
		private function connect(start:int, end:int, color:uint):void
		{
			this._strokeSprite.graphics.lineStyle(3, color);
			this._strokeSprite.graphics.moveTo(
				pointToSpriteX(start),
				pointToSpriteY(start)
			);
			this._strokeSprite.graphics.lineTo(
				pointToSpriteX(end),
				pointToSpriteY(end)
			);
		}
		
		private function pointToSpriteX(value:int):Number
		{
			return ((value % this._dotsSimulation.gridWidth) + 0.5) * this._spaceWidth;
		}
		
		private function pointToSpriteY(value:int):Number
		{
			return (int(value / this._dotsSimulation.gridWidth) + 0.5) * this._spaceHeight;
		}
	}
}

import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextLineMetrics;

class DotSpaceRender extends Sprite
{
	public function DotSpaceRender(index:int, spaceWidth:int, spaceHeight:int)
	{
		this.graphics.beginFill(0x0, 1);
		this.graphics.drawCircle(spaceWidth / 2, spaceHeight / 2, 3);
		
		var textField:TextField = new TextField();
		textField.width = spaceWidth;
		textField.autoSize = TextFieldAutoSize.CENTER;
		textField.text = index.toString();

		var metrics:TextLineMetrics = textField.getLineMetrics(0);
		textField.height = metrics.height + 4;
		textField.x = (spaceWidth / 2) - (textField.width / 2);
		textField.y = (spaceHeight / 2) - textField.height - 4;
		this.addChild(textField);
	}
}